﻿// ------------------------------------------------------------------------
// 项目名称：Canroc.Net 
// 版权归属：Canroc（https://gitee.com/canroc）
//
// 许可证信息
// Canroc.Net项目主要遵循 Apache 许可证（版本 2.0）进行分发和使用。许可证位于源代码树根目录中的 LICENSE-APACHE 文件。
//
// 使用条款：
// 1.使用本项目应遵守相关法律法规和许可证的要求。
// 2.不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动。
// 3.任何基于本项目二次开发而产生的一切法律纠纷和责任，我们不承担任何责任
//
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
//
// 其他重要信息
// Canroc.Net 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// ------------------------------------------------------------------------

using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace Canroc.Net.Core.Helper;

/// <summary>
///     微信支付助手
/// </summary>
public static class WeChatPayHelper
{
    /// <summary>
    ///     SHA256 With RSA 验签
    /// </summary>
    /// <param name="message">消息</param>
    /// <param name="signature">签名信息</param>
    /// <param name="certificate">证书信息</param>
    /// <returns></returns>
    public static bool SHA256WithRSAVerifyData(string message, string signature, string certificate)
    {
        var messageBytes = Encoding.UTF8.GetBytes(message);
        var signatureBytes = Convert.FromBase64String(signature);

        try
        {
            // 提取证书内容为纯字符串
            var base64X509Cert = certificate.Replace("-----BEGIN CERTIFICATE-----", "")
                .Replace("-----END CERTIFICATE-----", "").Replace("\r", "").Replace("\n", "");
            // 将证书内容转为字节数组
            var x509Cert = Convert.FromBase64String(base64X509Cert);
            // 创建一个X509证书对象
            X509Certificate2 cert = new(x509Cert);
            var rsa = cert.PublicKey.GetRSAPublicKey();
            if (rsa is null)
            {
                return false;
            }

            return rsa.VerifyData(messageBytes, signatureBytes, HashAlgorithmName.SHA256,
                RSASignaturePadding.Pkcs1);
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    ///     AEAD_AES_256_GCM 解密
    /// </summary>
    /// <param name="key">APIv3Key</param>
    /// <param name="ciphertext">密文</param>
    /// <param name="nonce">随机串</param>
    /// <param name="id">附加内容</param>
    /// <returns></returns>
    public static string AEAD_AES_256_GCMDecryption(string key, string ciphertext, string nonce, string? id)
    {
        GcmBlockCipher gcmBlockCipher = new(new AesEngine());
        AeadParameters aeadParameters = new(
            new KeyParameter(Encoding.UTF8.GetBytes(key)),
            128,
            Encoding.UTF8.GetBytes(nonce),
            id is not null ? Encoding.UTF8.GetBytes(id) : null
        );
        gcmBlockCipher.Init(false, aeadParameters);
        var data = Convert.FromBase64String(ciphertext);
        var plaintext = new byte[gcmBlockCipher.GetOutputSize(data.Length)];
        var length = gcmBlockCipher.ProcessBytes(data, 0, data.Length, plaintext, 0);
        gcmBlockCipher.DoFinal(plaintext, length);

        return Encoding.UTF8.GetString(plaintext);
    }
}